package org.benetech.util;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Utilities for dealing with HTML files.
 * @author Reuben Firmin
 */
public class HTMLUtils {

	private static Pattern DOCTYPE_PATTERN = Pattern.compile("<![Dd][Oo][Cc][Tt][Yy][Pp][Ee]");
	private static Pattern XML_PATTERN = Pattern.compile("<\\?[Xx][Mm][Ll][.[^\\?]]*\\?>");

	/**
	 * Add a "loose" html DOCTYPE definition to the html file, if a DOCTYPE could not be found. Trim any stuff before
	 * the <?xml header.
	 * @param htmlFile the html file to work on
	 * @throws IOException if file access fails
	 */
	public static void addDocTypeIfNonexistent(final File htmlFile)
	throws IOException
	{
		final String fileContents = FileUtils.getFileAsString(htmlFile, null);
		final Matcher docTypeMatcher = DOCTYPE_PATTERN.matcher(fileContents);
		final Matcher xmlHeadMatcher = XML_PATTERN.matcher(fileContents);
		final StringBuffer out = new StringBuffer();
		boolean insert = false;
		boolean docType = false;
		if (xmlHeadMatcher.find()) {
			out.append(fileContents.substring(xmlHeadMatcher.start(), xmlHeadMatcher.end()));
			insert = true;
		}
		if (!docTypeMatcher.find()) {
			out.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" ")
				.append("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
			docType = true;
		}
		out.append(insert ? fileContents.substring(xmlHeadMatcher.end()) : fileContents);
		// if we've fixed the xml heading, and/or inserted a doctype, write the file
		if (docType || xmlHeadMatcher.start() > 0) {
			FileUtils.writeToFile(htmlFile, out.toString().getBytes());
		}
	}

	/**
	 * Replaces all spaces with %20 since a url cannot have a space in it.
	 * @param url The url in which to make the substitution
	 * @return The url after the substitution has been made
	 */
	public static String escape(final String string) {
		try {
			return URLEncoder.encode(string, "ISO-8859-1");
		} catch (UnsupportedEncodingException e) {
			return string;
		}
	}
}
